package com.yanqu.road.server.gameplayer.module.activity.xiayue;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.args.XiaYueCombArgs;
import com.yanqu.road.entity.activity.xiayue.XiaYueUserData;
import com.yanqu.road.entity.activity.xiayue.config.XiaYueAnimalConfig;
import com.yanqu.road.entity.activity.xiayue.config.XiaYueCombConfig;
import com.yanqu.road.entity.activity.xiayue.config.XiaYueConfig;
import com.yanqu.road.entity.activity.xiayue.config.XiaYuePlaceConfig;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogXiaYueSearch;
import com.yanqu.road.logic.bussiness.activity.XiaYueBusiness;
import com.yanqu.road.pb.activity.XiaYueActivityProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.xiayue.XiaYueMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.pb.XiaYuePb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.property.Property;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class XiaYueModule extends GeneralModule {

    private XiaYueUserData userData;

    public XiaYueModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        XiaYueConfig xiaYueConfig = XiaYueMgr.getXiaYueConfig();
        if (xiaYueConfig != null && ActivityMgr.activityInShowTime(xiaYueConfig.getActivityInfo())) {
            userData = XiaYueBusiness.getXiaYueUserData(xiaYueConfig.getActivityInfo().getActivityId(), getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData != null) {
            if (userData.isInsertOption()) {
                XiaYueBusiness.addXiaYueUserData(userData);
            } else if (userData.isUpdateOption()) {
                XiaYueBusiness.updateXiaYueUserData(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        syncConfig();
        initUserData();
        syncData();
        combChange();
    }

    public synchronized void initUserData() {
        // 系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.XiaYueActivity.getValue())) {
            return;
        }

        // 没有活动
        XiaYueConfig config = XiaYueMgr.getXiaYueConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        ActivityInfo activityInfo = config.getActivityInfo();

        // 已经有数据了
        if (userData != null && userData.getActivityId() == activityInfo.getActivityId()) {
            return;
        }

        XiaYueUserData tmpUserData = new XiaYueUserData();
        tmpUserData.setActivityId(activityInfo.getActivityId());
        tmpUserData.setUserId(getUserId());
        tmpUserData.setScore(0);
        tmpUserData.setAnimalProp(new Property());

        List<Integer> npcList = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 4; i++) {
            npcList.add(XiaYueMgr.getRandomNpcId(random));
        }
        tmpUserData.setNpcList(npcList);

        tmpUserData.setCommonTimes(0);
        tmpUserData.setCurPlace(config.getInitPlaceId());
        tmpUserData.setInsertOption();
        userData = tmpUserData;
    }

    public void syncConfig() {
        XiaYueConfig xiaYueConfig = XiaYueMgr.getXiaYueConfig();
        if (xiaYueConfig == null || !ActivityMgr.activityInShowTime(xiaYueConfig.getActivityInfo())) {
            return;
        }

        XiaYueActivityProto.XiaYueSyncConfigRespMsg.Builder builder = XiaYuePb.parseXiaYueSyncConfigRespMsg(xiaYueConfig, player.getLanguage());
        player.sendPacket(ClientProtocol.U_XIAYUE_SYNC_CONFIG, builder);
    }

    public void syncData() {
        if (userData == null) {
            return;
        }

        XiaYueActivityProto.XiaYueSyncUserDataRespMsg.Builder builder = XiaYuePb.parseXiaYueSyncUserDataRespMsg(userData);
        player.sendPacket(ClientProtocol.U_XIAYUE_SYNC_DATA, builder);
    }

    /**
     * 搜寻
     */
    public int search(int times) {
        if (userData == null) {
            return GameErrorCode.E_XIAYUE_NO_UNLOCK;
        }
        XiaYueConfig xiaYueConfig = XiaYueMgr.getXiaYueConfig();
        if (!ActivityMgr.activityInTime(xiaYueConfig.getActivityInfo())) {
            return GameErrorCode.E_XIAYUE_NO_IN_TIME;
        }
        if (times != 1 && times != 10) {
            return GameErrorCode.E_XIAYUE_SEARCH_TIMES_ERRROR;
        }

        // 判断消耗
        int costNum = xiaYueConfig.getCostEnergyList().get(times == 10 ? 1 : 0);
        Property cost = new Property(xiaYueConfig.getSearchItemId(), BigInteger.valueOf(costNum));
        if (!player.getModule(CurrencyModule.class).currencyIsEnough(cost)) {
            return GameErrorCode.E_XIAYUE_SEARCH_COST_NO_ENOUGH;
        }

        int commonTimes = userData.getCommonTimes();
        List<Integer> npcList = new ArrayList<>(userData.getNpcList());
        List<XiaYueActivityProto.XiaYueSearchDataMsg> searchDataMsgList = new ArrayList<>();
        int scoreReward = 0;
        Property animalReward = new Property();
        int lastPlaceId = 0;
        List<LogXiaYueSearch> logXiaYueSearchList = new ArrayList<>();

        // 搜寻动物
        Random random = new Random();
        for (int i = 0; i < times; i++) {
            XiaYuePlaceConfig placeConfig = XiaYueMgr.searchPlace(commonTimes, random);
            XiaYueAnimalConfig animalConfig = XiaYueMgr.searchAnimal(placeConfig.getId(), commonTimes, random);
            // 组装结果
            if (animalConfig.getQuality() == xiaYueConfig.getGuaranteeQuality()) {
                commonTimes = 0;
                searchDataMsgList.add(XiaYuePb.parseXiaYueSearchDataMsg(placeConfig.getId(), animalConfig.getId(), xiaYueConfig.getMaidenNpcId()).build());
            } else {
                commonTimes++;
                int addNpcId = XiaYueMgr.getRandomNpcId(random);
                searchDataMsgList.add(XiaYuePb.parseXiaYueSearchDataMsg(placeConfig.getId(), animalConfig.getId(), addNpcId).build());
                npcList.remove(0);
                npcList.add(addNpcId);
            }
            scoreReward += animalConfig.getScore();
            animalReward.addProperty(animalConfig.getId(), BigInteger.ONE);
            lastPlaceId = placeConfig.getId();

            logXiaYueSearchList.add(new LogXiaYueSearch(
                    userData.getActivityId(),
                    userData.getUserId(),
                    placeConfig.getId(),
                    animalConfig.getId(),
                    animalConfig.getQuality(),
                    commonTimes
            ));
        }

        Property reward = new Property();
        reward.addProperty(xiaYueConfig.getScoreItemId(), BigInteger.valueOf(scoreReward));

        // 扣消耗
        player.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.XiaYueActivity, eLogMoneyType.XiaYueSearchCost);

        // 加奖励
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.XiaYueActivity, eLogMoneyType.XiaYueSearchGet);
        userData.setScore(userData.getScore() + scoreReward);
        userData.getAnimalProp().addProperty(animalReward);
        userData.setUpdateOption();
        userData.setNpcList(npcList);
        userData.setCommonTimes(commonTimes);
        userData.setCurPlace(lastPlaceId);

        // 积分变化
        player.notifyListener(eGamePlayerEventType.XiaYueScoreRank.getValue(), userData.getScore());
        player.notifyListener(eGamePlayerEventType.XiaYueCrossScoreRank.getValue(), userData.getScore());

        // 组合变化
        combChange();

        // 同步数据
        syncData();

        // 日志
        LogMgr.addLogXiaYueSearch(logXiaYueSearchList);

        // 返回
        XiaYueActivityProto.XiaYueSearchRespMsg.Builder builder = XiaYueActivityProto.XiaYueSearchRespMsg.newBuilder();
        builder.setRet(0);
        builder.addAllSearchList(searchDataMsgList);
        player.sendPacket(ClientProtocol.U_XIAYUE_SEARCH, builder);
        return 0;
    }

    /**
     * 组合次数变化
     */
    public void combChange() {
        XiaYueConfig xiaYueConfig = XiaYueMgr.getXiaYueConfig();
        if (userData == null || xiaYueConfig == null || !ActivityMgr.activityInShowTime(xiaYueConfig.getActivityInfo())) {
            return;
        }

        Map<Integer, XiaYueCombConfig> combConfigMap = xiaYueConfig.getCombConfigMap();
        for (XiaYueCombConfig combConfig : combConfigMap.values()) {
            int times = Integer.MAX_VALUE;
            for (Integer animalId : combConfig.getElementList()) {
                int count = userData.getAnimalProp().getCountByGoodsId(animalId).intValue();
                if (count < times) {
                    times = count;
                }
                if (times == 0) break;
            }
            if (times == Integer.MAX_VALUE || times == 0) continue;
            // 更新组合次数
            player.notifyListener(eGamePlayerEventType.XiaYueCombTimes.getValue(), new XiaYueCombArgs(combConfig.getCombId(), times));
        }
    }

}
